package com.lightsaber.trade.core.web.home;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.xwork.StringUtils;
import org.apache.struts2.interceptor.SessionAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContextHolder;

import com.lightsaber.trade.core.common.constants.AppConstant;
import com.lightsaber.trade.core.entity.account.Authority;
import com.lightsaber.trade.core.entity.account.nopersist.HomeMenuBar;
import com.lightsaber.trade.core.entity.account.nopersist.MenuBar;
import com.lightsaber.trade.core.service.account.AuthorityService;
import com.lightsaber.trade.core.service.account.MenuService;
import com.lightsaber.trade.core.service.account.impl.UserDetailsImpl;
import com.opensymphony.xwork2.ActionSupport;

/**
 * Prepare parameters for Home page.
 * 
 * @author LiuJian
 */
public class HomeAction extends ActionSupport implements SessionAware {

    private static final long serialVersionUID = 9215064230683326036L;

    private static final Logger log = LoggerFactory.getLogger(HomeAction.class);

    @Autowired
    private transient MenuService menuService;
    @Autowired
    private AuthorityService authorityService;

    public static final String ROLE_CODE = "roleCode";

    private String roleCode;

    private String menu;

    private Map<String, Object> session;

    @Override
    public String execute() throws Exception {

        roleCode = (String) session.get(ROLE_CODE);

        if (StringUtils.isNotBlank(roleCode)) {
            return SUCCESS;
        }

        // Set the first role code into session
        UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();

        String[] roles = userDetails.getRoleList();
        if (roles != null && roles.length > 0) {
            roleCode = roles[0];
            changeRole();
        }

        return SUCCESS;
    }

    public String changeRole() throws Exception {
        if (roleCode == null)
            return SUCCESS;

        session.put(ROLE_CODE, roleCode);

        // ---------- Change GrantedAuthority on role changed-----------START
        UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        String userName = userDetails.getUsername();

        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

        List<Authority> authoritiesList = authorityService.findByUserAndRole(userName, roleCode);
        if (authoritiesList.isEmpty()) {
            return SUCCESS;
        }
        for (Authority authority : authoritiesList) {
            authorities.add(new GrantedAuthorityImpl(AppConstant.AUTHORITY_PREFIX
                    + authority.getName()));
        }

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Authentication newAuthentication = new UsernamePasswordAuthenticationToken(
                authentication.getPrincipal(), authentication.getCredentials(), authorities);
        SecurityContextHolder.getContext().setAuthentication(newAuthentication);
        // ---------- Change GrantedAuthority on role changed-----------END

        return SUCCESS;
    }

    public String menuBar() throws Exception {
        execute();//当用记住密码, session过期, 任意请求,则要检查session中的roleCode
        
        // 1. Get role code from session
        String roleCode = (String) session.get(ROLE_CODE);

        UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        String userName = userDetails.getUsername();

        String language = getLocale().toString();
        MenuBar menuBar = menuService.generateMenuByRoleCode(userName, roleCode, language);
        menu = menuBar.toString();
        log.debug("homeMenuBar : {}", menu);

        return SUCCESS;
    }

    public String menuHtml() throws Exception {
        execute();//当用记住密码, session过期, 任意请求,则要检查session中的roleCode
        
        // 1. Get role code from session
        String roleCode = (String) session.get(ROLE_CODE);

        UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        String userName = userDetails.getUsername();

        String language = getLocale().toString();
        HomeMenuBar homeMenuBar = menuService.generateHomeMenuByRoleCode(userName, roleCode,
                language);
        menu = homeMenuBar.toString();
        log.debug("homeMenuBar : {}", menu);

        return SUCCESS;

    }

    public String getRoleCode() {
        return roleCode;
    }

    public void setRoleCode(final String roleCode) {
        this.roleCode = roleCode;
    }

    @Override
    public void setSession(final Map<String, Object> session) {
        this.session = session;
    }

    public String getMenu() {
        return menu;
    }
}
